[セッションレポート]Lambdaのコンテナイメージサポートについておさらい SVS209 Introducing container image support for AWS Lambda #reinvent
CX事業本部@大阪の岩田です。re:Invent 2020のWave 2で新たに公開されたセッション「SVS209 Introducing container image support for AWS Lambda 」を聴講したのでレポートさせて頂きます。
セッション概要
スピーカー:Chris Munns
以下公式サイトからの引用です。
This session covers one of the most requested new features for AWS Lambda: container image support. With container image support, developers can now package their Lambda functions and required dependencies using familiar container image tooling. You can also build and test your functions using familiar tools and services to analyze their contents and perform audits. Learn about the new developer workflow that is possible with this capability and how to potentially improve your continuous integration and deployment pipelines. Lastly, hear an explanation of container image security and how to share container images inside your organization.
ということでLambdaのコンテナイメージサポートについて学べるセッションとなっています。セッション動画及び資料は以下のリンクから確認できます。※要レジストレーション
Introducing container image support for AWS Lambda
以下セッションレポートです。
Lambdaのコンテナイメージサポートについて
- re:invent2020でLambdaのコンテナイメージサポートを発表した。この機能が実装された背景には以下のような目的がある。
- アプリケーションの依存関係管理を容易にする
- これまでコンテナベースのアプリケーションに利用してきたツールをLambdaベースのアプリケーションでも利用可能にする
- 巨大なアプリケーションをLambda実行環境にデプロイ可能にする
なぜコンテナイメージ形式をサポートするのか?
- ZIP形式のパッケージは以下のような課題を抱えていた
- Lambdaはサーバーレスなサービスでユーザーがサーバーを管理する必要はないが、サービスの裏側ではAmazon Linux、Amazon Linux2が動作している。
- OS依存のネイティブパッケージをLambdaに組み込むのは容易ではなかった
- ZIP形式のLambdaパッケージには最大250MBの制限があった
- 250Mだと不十分なケースがあった
- 例えばヘッドレスChromeやNumPyやSciPy
- コンテナイメージのパッケージをサポートすることで、以下のようなメリットが期待できる
- より大きなアプリケーションアーティファクト
- コンテナオーケストレーションに利用している既存のツールをそのまま利用できる
- セキュリティ関連のツール、コードの静的解析ツールといった、開発者のワークフローにで利用する様々なツールがそのまま利用できる。
- アーティファクトをECRに保存する点が従来のZIPパッケージとは異なる
- コンテナイメージ形式のLambdaを利用する場合は、まずコンテナイメージをECRにプッシュする必要がある
- Lambda Functionが実行されると、Lambda実行環境はコード(コンテナイメージ)をDLしてhandlerを実行する
- 実際にはLambda Functionの設定でコンテナイメージのURIを指定した際、Lambda実行環境にコンテナイメージをDLしてキャッシュしている
- このアーキテクチャによってコンテナイメージのサイズがパフォーマンスに及ぼす影響を最小化している。
- AWSはLambda Function用に各種ランタイムのコンテナイメージを公開している
- Node.js
- Python
- Java
- .NET
- Ruby
- Go
- Docker HubとECRのパブリックリポジトリ両方で利用可能
コンテナイメージサポートについて知っておくべきこと
- Lambdaはコンテナイメージの形式として以下のフォーマットをサポートしている
- Docker Image Manifest V2 Schema 2
- OCI Spec V1.0.0以降
- イメージの形式さえ準拠していれば、Amazon Linuxは必須という訳ではなく、独自のコンテナイメージをビルドして利用できる
- Dockerファイルにはコンテナイメージを構築する手順を記述する
FROM
でベースのコンテナイメージを指定COPY
でコンテナイメージにバンドルするファイルを指定RUN
で実行するコマンド(この例ではnpm install
)を指定CMD
でLambda Functionのエントリポイント(handler)を指定- サポートされる/されないDockerファイルの設定詳細についてはドキュメントを参照して欲しい
- コンテナイメージのサポートに関連する2つのコンポーネントがある - RIC(Runtime Interface Client) - コンテナイメージにバンドルされたコードがLambdaのランタイムAPIと通信できるようにするためのコンポーネント - コンテナイメージベースのLambda FunctionはZIPパッケージベースのLambda Functionでカスタムランタイムを利用する時と同じように動作する - bootstrap等の処理でLambaのランタイムAPIと通信する必要がある - RICはOSSとしてGitHub上で公開されている - RIE(Runtime Interface Emulator) - Lambda Functionをローカル環境でテストするための機能をサポート - SAM CLIとは少し動作が異なる - HTTPリクエストをイベントデータに変換してRICが理解できるようにする - RIEもOSSとしてGitHub上で公開されている
ビルド&デプロイのフロー
- デプロイフローは大きく変わらない
- まずはコードを書く
- コンテナイメージ形式のパッケージをデプロイする場合はDockerfileを用意する
docker build
またはdocker build
相当の処理を実行し、コンテナイメージをビルドする- コンテナイメージをテストする
- 必要に応じてコンテナオーケストレーションシステムにデプロイしてさらにテストすることも可能
- コンテナイメージをECRにプッシュする
-
Lambda Functionを作成してデプロイする
- SAM、Cloud Formation、その他各種のツールが利用可能
- Lambda Functionを更新する場合はコンテナイメージのプッシュだけでなく、Lambda Functionの設定(コンテナイメージのURI)変更が必要
- SAM CLIはサーバーレスアプリケーションの管理と構築を簡素化するツール
- 2020年12月のアップデートでSAM CLIにもコンテナイメージのサポートが追加された
- SAM CLIのdeployコマンドによって、これまで紹介したデプロイ手順が簡単に実行できる
- イメージの取得
- ECRリポジトリの作成
- イメージのアップロード
- コンテナイメージのデプロイ
- SAM CLIは他にも多くの機能をもち、ローカル環境でAPI GWのモック等が実行できる
- ローカル環境でのテストが用意になる
コンテナイメージ形式のLambdaで変わること/変わらないこと
- コンテナイメージのサポートにより、以下のような変更が発生する
- 大きなアーティファクトが利用可能に
- LambdaのランタイムAPIとコミュニケーションするためにRICを組み込む必要がある
- ランタイムがユーザー管理となる。つまり自動的には更新されない
- これはメリットでもあり、デメリットでもある
- ランタイムの自動更新による互換性の問題は考慮不要になるが、セキュリティパッチやバグフィックスの適用は開発者側の責任で実施する必要がある
- 逆に以下のような項目は変わらない
- Lambdaの実行モデル
- ストレージ
- ロギング、メトリクス、X-Rayとの統合
- 実行時間の上限15分のようなサービスの上限
- 請求
- Lambda Functionの構造は変わらない
- コードのエントリポイントはhandler
- Functionをトリガーしたイベントに関する情報はイベントオブジェクトから取得可能
- Function実行に関する情報はContextオブジェクトから取得可能
- Lambdaを呼び出すためのモデルは変わらない
- Lambdaを直接呼び出すためのソケットやポートというのは存在しない
- コンテナイメージ形式のLambdaであってもイベント駆動なアーキテクチャは変わらない
- 100以上のAWSサービスからLambdaを呼び出すことが可能
Lambdaに関連するストレージ
- Lambda Functionから利用できるメモリの上限を10GBに拡張した
- /tmp領域の上限は従来通り512MBのまま
- コンテナイメージのデプロイパッケージは10Gまで利用可能
- 機械学習のモデルや科学計算系のライブラリ...様々なツールをパッケージング可能
- Lambdaにおける外部ストレージの選択肢は大きく2つ考えられる
- S3...従来から利用されている選択肢
- EFS...2020年夏のアップデートにより利用可能に
Lambdaのリソース上限拡張
- より大きなLambda Functionsがサポートされるようになった
- メモリ10GB、6vCPUまで利用可能に
- メモリ割当が1769MBまでは利用可能なvCPUは1つだけ
- ほとんどのLambda Functionsはマルチスレッドではなく、マルチコアの恩恵は受けない
- しかし一部のユースケースではプロセスのフォークや、マルチスレッドな処理を実行している顧客もいる
- Kinesis、DynamoDB、SQSといったイベントソースと連携したバッチ処理を実装している場合など、上限拡張の恩恵が期待できるケースもある
Lambda Extensionsについて
- 2020年10月にLambda Extensionsの機能が発表された
- この機能を利用すると、サードパーティ製のツールをLambda実行環境に組み込むことができる
- HashiCorp、Splunk、Datadog、New RelicなどのExtensionが利用可能
- Lambda ExtensionsはLambda Layersを利用してサードパーティ製ツールをLambda実行環境に組み込む。コンテナイメージ形式のLambdaではLambda Layersが利用できないため、コンテナイメージ内にExtensionを組み込む必要がある。以下のような方法が利用できる。
- マルチステージビルドを利用し、Lambda Extensions用のコンテナイメージからコピーする
- Lambda Layerのコードを取得してコピーする
- マルチステージビルドを利用し、Lambda Extensions用のコンテナイメージからコピーする例
- レイヤーのコードを取得してコピーする例
- Lambdaの課金単位が100ms単位から1ms単位に更新された - 従来は100ms未満で実行が完了する場合でも100ms分の請求となっていた。同様に101msで実行が完了する場合は200ms分の請求となっていた。 - 100ms未満で実行が完了する場合に70~80%のコスト削減につながるケースも見られる - 2020年12月の請求サイクルから有効化された
ECRについて
- コンテナイメージ形式のLambdaを利用する場合、事前にECRにイメージをプッシュする必要がある
- S3にZIPパッケージを配置するのと比較して、ECRには以下のようなメリットがある
- ECRはデフォルトでプライベート
- IAMによるきめ細やかな権限管理
- CloudTrailによるロギング
- イメージ保存時、転送時の暗号化
- クロスアカウントのアクセス制御
- リージョン間レプリケーション
- サービスに統合された脆弱性スキャン機能
ローンチパートナーの紹介
- コンテナイメージサポートの追加にあたっては、このスライドに記載されているコンサルティングパートナーが協力してくれた
- コンテナイメージサポートが顧客のニーズに合った最適な形になるように、コンサルティングパートナーからのフィードバックを受けながらテストを重ねてきた
なんか見た事あるロゴが!!
感想
re:invent2020で発表されたLambdaのコンテナイメージサポートについておさらいできる良いセッションでした。従来のZIP形式とコンテナイメージ形式それぞれのメリット&デメリットをしっかり抑えながら、最適な選択を取れるようにしていきたいと思います。